/**
 * 
 */
package uicgas.register;

import java.awt.Container;
import java.util.ArrayList;
import java.util.Queue;

import javax.swing.JOptionPane;
import javax.swing.JPanel;

import uicgas.communication.Communication;
import uicgas.globaldata.ActivationData;
import uicgas.globaldata.ControlMessage;
import uicgas.globaldata.CreditCard;
import uicgas.globaldata.GenericPumpList;
import uicgas.globaldata.MessagePayload;
import uicgas.globaldata.Messages;
import uicgas.globaldata.Password;
import uicgas.globaldata.Pump;
import uicgas.globaldata.SelfAnnouncement;
import uicgas.globaldata.Transaction;
import uicgas.globaldevice.MockPrinter;
import uicgas.register.GUI.MainRegister;

/**
 * @author Steve
 * @version 0.0.1
 * @date Nov, 12, 2010 
 */
public class RegisterLogic
{
	private static int MAX_NUM_PUMPS = 20;

	private Comunications myComUnit;
	private GenericPumpList Assitance;
	public Transaction pumptransactions[] = new Transaction[MAX_NUM_PUMPS];
	public Pump allPumps[] = new Pump[MAX_NUM_PUMPS];
	private Pump temppump;
	//private Queue AssistanceList = new Queue<>;
	Transaction currentTransaction;
	private GenericPumpList assistanceQueue;
	private boolean validCreditCard = false;
	private boolean passwordValidity = false;
	public MainRegister MainScreen;
	private int id = -1;

	public RegisterLogic()
	{
		id = this.hashCode();
		for (int i = 0; i < allPumps.length; i++)
		{
			allPumps[i] = new Pump();
		}
		myComUnit = new Comunications(this);
		myComUnit.start();
		if (this.getID() != -1)
		{
			SelfAnnouncement me = new SelfAnnouncement(this.getID(),
					this.getID());
			ControlMessage getmyPumps = new ControlMessage(
					Messages.ANNOUNCEALLCONNECTEDPUMPS, me);
			myComUnit.sendData(getmyPumps);
		}
		else
		{

		}
	}

	public Communication getCommunication()
	{
		return myComUnit;
	}

	public static void main(String[] args)
	{
		RegisterLogic register = new RegisterLogic();
		//RegisterGUI gui = new RegisterGUI();
		//gui.setVisible(true);
		register.printReceiptFromOutside(40);
		register.printReceiptFromOutside(10);
		register.validatePumpID(10, 10.00);
		//register.Pause(10);
		//System.out.println("TESTING");

	}

	//no longer needed
	//	private boolean GUI()
	//	{
	//		RegisterGUI gui = new RegisterGUI();
	//		return true;
	//		//TODO
	//	}

	public int startComm()
	{
		//Communication
		myComUnit = new Comunications(this);
		myComUnit.start(); //needs some work here.
		return 0;
	}

	public void printTransaction(Transaction currentTransaction)
	{
		MockPrinter myPrinter = new MockPrinter();
		myPrinter.print(currentTransaction);
	}

	private void storeTransaction(int pumpnumber)
	{
		JOptionPane.showConfirmDialog(null,
				"Now storing transaction from pump " + pumpnumber + ".",
				"Store Transaction Alert", 0);
	}

	private int validatePumpID(int pumpnumber, double dollarAmount)
	{
		if (JOptionPane.showConfirmDialog(null, "Was this the correct pump "
				+ pumpnumber + "?", "Confirm Pump", JOptionPane.YES_NO_OPTION) == 1)
		{
			//JOptionPane.showMessageDialog(null,"You hit no"); //used for testing
			return -1;
		}
		else
		{
			//JOptionPane.showMessageDialog(null, "You hit yes"); //used for testing
			if (JOptionPane.showConfirmDialog(null,
					"Was this the correct Dollar amount $" + dollarAmount
							+ "0?", "Confirm Dollar Amount",
					JOptionPane.YES_NO_OPTION) == 0)
			{
				return 1;
			}
			else
			{
				return -1;
			}
		}
	}

	/**
	 * 
	 * @return double integer value: returns the entered amount from the user
	 * @return -1 on error.
	 */
	public double inputDollarAmmount()
	{
		String temp = JOptionPane
				.showInputDialog(
						null,
						"Please input the Dollar amount that the Customer wishes to pay in the form of \"$0.00\".",
						"Input Dollar Amount", 0);
		String temp2 = "";
		double tempAmount;
		if (temp != null)
		{
			if (!temp.isEmpty())
			{
				if (temp.charAt(0) == '$')
				{
					for (int i = 0; i < temp.length() - 1; i++)
					{
						temp2 = temp2 + temp.charAt(i + 1);
					}
					tempAmount = Double.parseDouble(temp2);
					return tempAmount;
				}
			}
			else
			{
				return -1.00;
			}
		}
		return -1.00;
	}

	public void initiateTransaction()
	{
		//TODO we need to start a transaction here for some given pump, also upon receiving a transaction we need to perform some work with it here. 
	}

	private int getChangeDueAtPump()
	{
		return 0;
	}

	public void notifyAssistance()
	{
		MainScreen.blinkAssistance();
	}

	public void changePumpState(MessagePayload inData)
	{
		MainScreen.updateAllButtons();
	}

	private void printReceiptFromOutside(int pumpID)
	{
		if (pumpID < 19 && pumpID >= 0)
		{
			Transaction TempTransaction = this.pumptransactions[pumpID];
		}
		else
		{
			JOptionPane
					.showMessageDialog(
							null,
							"There was an error while printing the receipt. \nError: Bad Pump ID",
							"Printing Error", JOptionPane.ERROR_MESSAGE);
		}
	}

	private void changeRecomPassword(Password password)
	{
		//perform validateion and then change the password of the system.
		//password.
	}

	private boolean validateRecomPassword(Password password)
	{
		String passwordTemp = JOptionPane.showInputDialog(null,
				"please Enter Recommissioning password", "Password Request",
				JOptionPane.QUESTION_MESSAGE);
		while (!password.checkPassword(passwordTemp))
		{
			passwordTemp = JOptionPane.showInputDialog(null,
					"please Enter Recommissioning password",
					"Password Request", JOptionPane.QUESTION_MESSAGE);
		}
		return true;
		//		if (password.checkPassword(passwordTemp))
		//		{
		//			return true;
		//		}
		//		else
		//		{
		//			return false;
		//		}
	}

	public boolean validateCardInfo(CreditCard card, Pump pump)
	{
		ControlMessage cardValidationMsg = new ControlMessage(
				Messages.VALIDATECARD, card);
		myComUnit.sendData(cardValidationMsg);
		return false;
	}

	/**
	 * Used to provide a pauseing action to the system.
	 * @author Steve
	 * @param iTimeInSeconds, input in integers the time in which the system is to pause
	 */
	private void Pause(int iTimeInSeconds)
	{
		long time_start, time_end;

		time_start = System.currentTimeMillis();
		time_end = System.currentTimeMillis() + (iTimeInSeconds * 1000);

		do
		{
			time_start = System.currentTimeMillis();

		}
		while (time_start < time_end);
		{
			//do nothing, just wait
		}
	}

	/**
	 * Used to notify the system of a pump asking for assistance.
	 * @param inData
	 */
	public void NotifyAssistance(MessagePayload inData)
	{
//		if (i)
//		{
//			Pump thePump = (Pump) inData;
//			this.assistanceQueue.getQueue().add(thePump);
//			MainScreen.blinkAssistance();
//			//		if(this.MainScreen.
//			//				thePump.getID()
//		}
		this.assistanceQueue = (GenericPumpList) inData;
		MainScreen.blinkAssistance();
	}

	public GenericPumpList getAssistanceQueue()
	{
		return this.assistanceQueue;
	}

	public boolean removePumpfromQueue(int id, Pump thePump)
	{
		if (this.assistanceQueue.getQueue().remove(thePump))
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	public void NotifyInvalidCard()
	{
		JOptionPane
				.showMessageDialog(
						null,
						"Were sorry but that card is invalid. Please try a different creditcard.",
						"UIC Gas - Invalid Creditcard",
						JOptionPane.WARNING_MESSAGE);
	}

	public int getID()
	{
		return id % 5;
	}

	public void generateNewID()
	{
		id++;
		id = id % 5;
	}

	/**
	 * This method handles when the server announces all available pumps.
	 * @author Steve
	 * @param inData - Expected to be of type GenericPumpList.
	 */
	public void AnnouncePump(MessagePayload inData)
	{
		//make sure we don't have a null data package coming in
		if (inData != null)
		{
			Pump[] decomPump = new Pump[20];
			//System.out.println("WERE ANNOUNCING PUMPS"); //used for debug opperations
			ArrayList<Pump> mylist = new ArrayList();
			GenericPumpList newlist = (GenericPumpList) inData;
			try
			{

			}
			catch (NullPointerException e)
			{
				//there is an error here.
			}
			mylist = newlist.getPumpList();
			//allPumps = (Pump[])mylist.toArray();
			allPumps = new Pump[MAX_NUM_PUMPS];
			for (int i = 0; i < mylist.size(); i++)
			{
				Pump temp = mylist.get(i);
				int id = temp.getID();
				allPumps[id] = temp;
			}
			try
			{
				decomPump = newlist.getQueue().toArray(decomPump);
				//System.out.println("NO EXCEPTION");
			}
			catch (NullPointerException e)
			{
				//System.out.println("DECOMPUMP - EXCEPTION"); //used for Debug
				//do nothing with the pointerException
			}
			//make sure we have an actual populated array to work with otherwise do nothing with this section
			if (decomPump[0] != null)
			{
				if (decomPump != null)
				{ //Add all the decommed Pumps to the list.
					for (int i = 0; i < decomPump.length; i++)
					{
						//have to check each and every element because
						//there's no way to tell how many there are
						//length is the total size of the array
						//in this case 20. It will always be 20.
						if (decomPump[i] != null)
						{
							Pump temp = decomPump[i];
							System.out.println(i);
							int id = temp.getID();
							//System.out.println("adding decompump " + id); //used for debuging
							allPumps[id] = temp;
						}
					}
				}
			}
			//update all of the buttons on the MainPumpScreen can result in a null exception so do try/catch
			try
			{
				MainScreen.updateAllButtons();
			}
			catch (NullPointerException e)
			{
				//dont do anything with it
			}
		}
	}

	public void ActivatePump(MessagePayload inData)
	{
		if (inData != null)
		{
			if(inData.getClass().equals(CreditCard.class))
			{
				//System.out.println("Passed Credit Card test in ActivatePump"); //used for debug opperations
				CreditCard PumpCard = (CreditCard) inData;
				validCreditCard = true;
			}
			if(inData.getClass().equals(Password.class))
			{
				passwordValidity = true;
			}
			//for
		}
	}
	public boolean getPasswordValidity()
	{
		boolean temp = passwordValidity;
		passwordValidity = false;
		return temp;
	}
	public boolean getCardValidity()
	{
		boolean temp = validCreditCard;
		validCreditCard = false;
		return temp;
	}

	public void AnnounceTransaction(MessagePayload inData)
	{
		//Nothing needs to be done here yet.
	}

	public void updatePumps()
	{
		SelfAnnouncement me = new SelfAnnouncement(this.getID(),
				this.getID());
		ControlMessage getmyPumps = new ControlMessage(
				Messages.ANNOUNCEALLCONNECTEDPUMPS, me);
		this.getCommunication().sendData(getmyPumps);
		Pause(2);
		this.MainScreen.updateAllButtons();
		
	}
}
